//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V1.0.0
#include "timer_bsp.h"
#include "gd32f4xx_misc.h"
#include "gd32f4xx_rcu.h"


/*定时器总管理结构体*/
typedef struct
{
	void (*Basic_IT_CB)(void);        //基本中断回调函数
	WHT_DMA_Config_t DMA_Config_UP;   //DMA配置
    WHT_DMA_Config_t DMA_Config_CCR1; //DMA配置
	WHT_DMA_Config_t DMA_Config_CCR2;
	WHT_DMA_Config_t DMA_Config_CCR3;
	WHT_DMA_Config_t DMA_Config_CCR4;
}WHT_Data_t;

static WHT_Data_t WHT_TIMER1;
static WHT_Data_t WHT_TIMER2;
static WHT_Data_t WHT_TIMER3;
static WHT_Data_t WHT_TIMER4;
static WHT_Data_t WHT_TIMER5;
static WHT_Data_t WHT_TIMER6;
static WHT_Data_t WHT_TIMER7;
static WHT_Data_t WHT_TIMER8;
static WHT_Data_t WHT_TIMER9;
static WHT_Data_t WHT_TIMER10;
static WHT_Data_t WHT_TIMER11;
static WHT_Data_t WHT_TIMER12;
static WHT_Data_t WHT_TIMER13;
static WHT_Data_t WHT_TIMER14;

#define WHT_TIMER     ((WHT_Data_t*)config->Private_Data)//简化操作

/*基本定时器中断优先级配置*/
static void WHT_Timer_BSP_Basic_NVIC_Configuration(const WHT_Timer_Config_t *config)
{
	IRQn_Type IRQn;

    /* 配置中断源 */
    switch (config->Name)
    {
	case Timer1: IRQn = TIMER0_UP_TIMER9_IRQn; break;
    case Timer2: IRQn = TIMER1_IRQn; break;
    case Timer3: IRQn = TIMER2_IRQn; break;
    case Timer4: IRQn = TIMER3_IRQn; break;
#if defined (GD32F450) || defined (GD32F470) || defined (GD32F405) || defined (GD32F425) || defined (GD32F407) || defined (GD32F427)
    case Timer5: IRQn = TIMER4_IRQn; break;
	case Timer6: IRQn = TIMER5_DAC_IRQn; break;
	case Timer7: IRQn = TIMER6_IRQn; break;
#endif
	case Timer8: IRQn = TIMER7_UP_TIMER12_IRQn; break;
    case Timer9: IRQn = TIMER0_BRK_TIMER8_IRQn; break;
    case Timer10:IRQn = TIMER0_UP_TIMER9_IRQn; break;
    case Timer11:IRQn = TIMER0_TRG_CMT_TIMER10_IRQn; break;
    case Timer12:IRQn = TIMER7_BRK_TIMER11_IRQn; break;
	case Timer13:IRQn = TIMER7_UP_TIMER12_IRQn; break;
    case Timer14:IRQn = TIMER7_TRG_CMT_TIMER13_IRQn; break;
    default:
        return;
    }

	NVIC_SetPriority(IRQn, ((WHT_Timer_Basic_Config_t*)config->Config)->PreemptionPriority);
	NVIC_EnableIRQ(IRQn);
}
/*高级定时器GPIO初始化*/
static void WHT_Timer_BSP_GPIO_Init(const WHT_Timer_Config_t* config)
{
	WHT_Timer_PWM_Out_Config_t* PWM_Config;

	PWM_Config = (WHT_Timer_PWM_Out_Config_t*)config->Config;

	for (unsigned char i = 0; i < config->Config_Count; i++)
	{
		/*输出比较通道GPIO*/
		WHT_GPIO_BSP.WHT_Set_Clock(PWM_Config[i].Normal_Output_GPIO_Port, ENABLE);
		WHT_GPIO_BSP.WHT_Set_Pin(PWM_Config[i].Normal_Output_GPIO_Port, PWM_Config[i].Normal_Output_GPIO_Pin, Low);
		WHT_GPIO_BSP.WHT_Set_Mode(PWM_Config[i].Normal_Output_GPIO_Port, PWM_Config[i].Normal_Output_GPIO_Pin, Mode_AF_PP);
		/*输出比较通道互补通道GPIO*/
		if (PWM_Config[i].Complementary_Output_State == ENABLE)
		{
			WHT_GPIO_BSP.WHT_Set_Clock(PWM_Config[i].CO_Output_GPIO_Port, ENABLE);
			WHT_GPIO_BSP.WHT_Set_Pin(PWM_Config[i].CO_Output_GPIO_Port, PWM_Config[i].CO_Output_GPIO_Pin, Low);
			WHT_GPIO_BSP.WHT_Set_Mode(PWM_Config[i].CO_Output_GPIO_Port, PWM_Config[i].CO_Output_GPIO_Pin, Mode_AF_PP);
		}
		/*输出比较通道刹车通道GPIO*/
		if (PWM_Config[i].Brake_Output_State == ENABLE)
		{
			WHT_GPIO_BSP.WHT_Set_Clock(PWM_Config[i].Brake_Output_GPIO_Port, ENABLE);
			WHT_GPIO_BSP.WHT_Set_Pin(PWM_Config[i].Brake_Output_GPIO_Port, PWM_Config[i].Brake_Output_GPIO_Pin, Low);// BKIN引脚默认先输出低电平
			WHT_GPIO_BSP.WHT_Set_Mode(PWM_Config[i].Brake_Output_GPIO_Port, PWM_Config[i].Brake_Output_GPIO_Pin, Mode_AF_PP);
		}

		switch (config->Name)
		{
		case Timer1:
		case Timer2://定时器1、2的复用功能是一家
			WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Normal_Output_GPIO_Port, PWM_Config[i].Normal_Output_GPIO_Pin, AFIO_TIM1);
			if (PWM_Config[i].Complementary_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].CO_Output_GPIO_Port, PWM_Config[i].CO_Output_GPIO_Pin, AFIO_TIM1);
			if (PWM_Config[i].Brake_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Brake_Output_GPIO_Port, PWM_Config[i].Brake_Output_GPIO_Pin, AFIO_TIM1);
			break;
		case Timer3:
		case Timer4:
		case Timer5://定时器3、4、5的复用功能是一家
			WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Normal_Output_GPIO_Port, PWM_Config[i].Normal_Output_GPIO_Pin, AFIO_TIM3);
			if (PWM_Config[i].Complementary_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].CO_Output_GPIO_Port, PWM_Config[i].CO_Output_GPIO_Pin, AFIO_TIM3);
			if (PWM_Config[i].Brake_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Brake_Output_GPIO_Port, PWM_Config[i].Brake_Output_GPIO_Pin, AFIO_TIM3);
			break;
		case Timer8:
		case Timer9:
		case Timer10:
		case Timer11://定时器8、9、10、11的复用功能是一家
			WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Normal_Output_GPIO_Port, PWM_Config[i].Normal_Output_GPIO_Pin, AFIO_TIM8);
			if (PWM_Config[i].Complementary_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].CO_Output_GPIO_Port, PWM_Config[i].CO_Output_GPIO_Pin, AFIO_TIM8);
			if (PWM_Config[i].Brake_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Brake_Output_GPIO_Port, PWM_Config[i].Brake_Output_GPIO_Pin, AFIO_TIM8);
			break;
		case Timer12:
		case Timer13:
		case Timer14:
			WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Normal_Output_GPIO_Port, PWM_Config[i].Normal_Output_GPIO_Pin, AFIO_TIM12);
			if (PWM_Config[i].Complementary_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].CO_Output_GPIO_Port, PWM_Config[i].CO_Output_GPIO_Pin, AFIO_TIM12);
			if (PWM_Config[i].Brake_Output_State == ENABLE)
				WHT_GPIO_BSP.WHT_Set_AFIO(PWM_Config[i].Brake_Output_GPIO_Port, PWM_Config[i].Brake_Output_GPIO_Pin, AFIO_TIM12);
			break;
		default:
			return;
		}
	}
}
/*定时器时钟源使能*/
static void WHT_Timer_BSP_Clock_Cmd(const WHT_Timer_Config_t* config, ControlStatus state)
{
    switch (config->Name)//开启定时器时钟
    {
    case Timer1: rcu_periph_clock_enable(RCU_TIMER0); break;
    case Timer2: rcu_periph_clock_enable(RCU_TIMER1); break;
    case Timer3: rcu_periph_clock_enable(RCU_TIMER2); break;
    case Timer4: rcu_periph_clock_enable(RCU_TIMER3); break;
    case Timer5: rcu_periph_clock_enable(RCU_TIMER4); break;
    case Timer6: rcu_periph_clock_enable(RCU_TIMER5); break;
    case Timer7: rcu_periph_clock_enable(RCU_TIMER6); break;
    case Timer8: rcu_periph_clock_enable(RCU_TIMER7); break;
    case Timer9: rcu_periph_clock_enable(RCU_TIMER8); break;
    case Timer10:rcu_periph_clock_enable(RCU_TIMER9); break;
    case Timer11:rcu_periph_clock_enable(RCU_TIMER10);break;
    case Timer12:rcu_periph_clock_enable(RCU_TIMER11);break;
    case Timer13:rcu_periph_clock_enable(RCU_TIMER12);break;
    case Timer14:rcu_periph_clock_enable(RCU_TIMER13);break;
    default:
        return;
    }
}

/*定时器时间配置*/
static void WHT_Timer_BSP_Set_Time(const WHT_Timer_Config_t* config)
{
    timer_parameter_struct TIM_TimeBaseInitStruct;
    unsigned int Clk_Div;
	double Cycle;

	Cycle = config->Cycle_ns * ((double)SystemCoreClock / 1000000000.0f);
	switch(config->Name)//APB1 = APB2/2;
	{
	case Timer2:
	case Timer3:
	case Timer4:
	case Timer5:
	case Timer6:
	case Timer7:
	case Timer12:
	case Timer13:
	case Timer14:Cycle /= 2;break;
	}

    for (Clk_Div = 1; Clk_Div < 65536; Clk_Div++)
    {
        if ((Cycle / Clk_Div) <= 65536)
            break;
    }

	WHT_Timer_BSP_Clock_Cmd(config, ENABLE);
	/*计数器的时钟分频*/
	TIM_TimeBaseInitStruct.prescaler = Clk_Div - 1;
	/*自动重装载寄存器值，累计TIM_Period+1个频率后产生一个更新或者中断*/
	TIM_TimeBaseInitStruct.period = Cycle / Clk_Div - 1;
	/*保存自动重装载值即分辨率*/
	((WHT_Timer_Config_t*)config)->Auto_Reload = TIM_TimeBaseInitStruct.period;
	/*时钟分频因子 ，配置死区时间要用*/
	TIM_TimeBaseInitStruct.clockdivision = TIMER_CKDIV_DIV1;
	/*设置向上计数*/
	TIM_TimeBaseInitStruct.alignedmode = TIMER_COUNTER_CENTER_UP;
	/*重复计数器的值，没用到*/
	TIM_TimeBaseInitStruct.repetitioncounter = 0;
	/*复位重置定时器，防止之前有残留配置*/
    timer_deinit(config->Name);
	/*初始化配置定时器*/
    timer_init(config->Name, &TIM_TimeBaseInitStruct);

    /*关闭所有中断*/
	timer_interrupt_disable(config->Name, TIMER_INT_UP);
	timer_interrupt_disable(config->Name, TIMER_INT_CH0);
	timer_interrupt_disable(config->Name, TIMER_INT_CH1);
	timer_interrupt_disable(config->Name, TIMER_INT_CH2);
	timer_interrupt_disable(config->Name, TIMER_INT_CH3);
	timer_interrupt_disable(config->Name, TIMER_INT_CMT);
	timer_interrupt_disable(config->Name, TIMER_INT_TRG);
	timer_interrupt_disable(config->Name, TIMER_INT_BRK);
    /*清除所有中断标志位*/
	timer_flag_clear(config->Name, TIMER_FLAG_UP);
	timer_flag_clear(config->Name, TIMER_FLAG_CH0);
	timer_flag_clear(config->Name, TIMER_FLAG_CH1);
	timer_flag_clear(config->Name, TIMER_FLAG_CH2);
	timer_flag_clear(config->Name, TIMER_FLAG_CH3);
	timer_flag_clear(config->Name, TIMER_FLAG_CMT);
	timer_flag_clear(config->Name, TIMER_FLAG_TRG);
	timer_flag_clear(config->Name, TIMER_FLAG_BRK);
	timer_flag_clear(config->Name, TIMER_FLAG_CH0O);
	timer_flag_clear(config->Name, TIMER_FLAG_CH1O);
	timer_flag_clear(config->Name, TIMER_FLAG_CH2O);
	timer_flag_clear(config->Name, TIMER_FLAG_CH3O);
    /*关闭计数器*/
	timer_disable(config->Name);
}
/*基本定时器*/
static void WHT_Timer_BSP_Basic(const WHT_Timer_Config_t* config)
{
	WHT_TIMER->Basic_IT_CB = ((WHT_Timer_Basic_Config_t*)config->Config)->Interrupt_Callback;
	WHT_TIMER->DMA_Config_UP.IT_Callback = WHT_TIMER->Basic_IT_CB;
	switch (config->Name)
	{
	case Timer1:WHT_TIMER->DMA_Config_UP.Periph = Periph_TIM1_UP;          WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM1_UP;          WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM1_UP;          break;
	case Timer2:WHT_TIMER->DMA_Config_UP.Periph = Periph_TIM2_UP_TIM2_CH3; WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM2_UP_TIM2_CH3; WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM2_UP_TIM2_CH3; break;
	case Timer3:WHT_TIMER->DMA_Config_UP.Periph = Periph_TIM3_CH4_TIM3_UP; WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM3_CH4_TIM3_UP; WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM3_CH4_TIM3_UP; break;
	case Timer4:WHT_TIMER->DMA_Config_UP.Periph = Periph_TIM4_UP;          WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM4_UP;          WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM4_UP;          break;
	case Timer5:WHT_TIMER->DMA_Config_UP.Periph = Periph_TIM5_CH3_TIM5_UP; WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM5_CH3_TIM5_UP; WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM5_CH3_TIM5_UP; break;
	case Timer6:WHT_TIMER->DMA_Config_UP.Periph = Periph_TIM6_UP;          WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM6_UP;          WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM6_UP;          break;
	case Timer7:WHT_TIMER->DMA_Config_UP.Periph = Periph_TIM7_UP_1;	       WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM7_UP_1;        WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM7_UP_1;        break;
	case Timer8:WHT_TIMER->DMA_Config_UP.Periph = Periph_TIM8_UP;          WHT_TIMER->DMA_Config_UP.Stream = Stream_TIM8_UP;          WHT_TIMER->DMA_Config_UP.Channel = Channel_TIM8_UP;          break;
	default:return;
   	}

	timer_dma_disable(config->Name, TIMER_DMA_UPD);//关闭定时器DMA更新
	WHT_Timer_BSP_Basic_NVIC_Configuration(config);
	/*将注册到DMA上*/
	WHT_DMA_BSP.WHT_Register(&WHT_TIMER->DMA_Config_UP);
	/*开启更新中断*/
	timer_interrupt_enable(config->Name, TIMER_INT_UP);
}
/*定时器输出触发*/
static void WHT_Timer_BSP_Output_Trigger(const WHT_Timer_Config_t* config)
{
	timer_master_output_trigger_source_select(config->Name, ((WHT_Timer_Out_Trigger_Config_t*)config->Config)->Out_Trigger);
}
/*定时器输出比较PWM*/
static void WHT_Timer_BSP_Output_Comparison(const WHT_Timer_Config_t* config)
{
	WHT_Timer_PWM_Out_Config_t* PWM_Config = (WHT_Timer_PWM_Out_Config_t*)config->Config;

	switch (config->Name)
	{
	case Timer1:
		WHT_TIMER->DMA_Config_CCR1.Stream = Stream_TIM1_CH1_1;                 WHT_TIMER->DMA_Config_CCR1.Channel = Channel_TIM1_CH1_1;
		WHT_TIMER->DMA_Config_CCR2.Stream = Stream_TIM1_CH2;                   WHT_TIMER->DMA_Config_CCR2.Channel = Channel_TIM1_CH2;
		WHT_TIMER->DMA_Config_CCR3.Stream = Stream_TIM1_CH3;                   WHT_TIMER->DMA_Config_CCR3.Channel = Channel_TIM1_CH3;
		WHT_TIMER->DMA_Config_CCR4.Stream = Stream_TIM1_CH4_TIM1_TRIG_TIM1_COM;WHT_TIMER->DMA_Config_CCR4.Channel = Channel_TIM1_CH4_TIM1_TRIG_TIM1_COM;
		break;
	case Timer2:
		WHT_TIMER->DMA_Config_CCR1.Stream = Stream_TIM2_CH1;          WHT_TIMER->DMA_Config_CCR1.Channel = Channel_TIM2_CH1;
		WHT_TIMER->DMA_Config_CCR2.Stream = Stream_TIM2_CH2_TIM2_CH4; WHT_TIMER->DMA_Config_CCR2.Channel = Channel_TIM2_CH2_TIM2_CH4;
		WHT_TIMER->DMA_Config_CCR3.Stream = Stream_TIM2_UP_TIM2_CH3;  WHT_TIMER->DMA_Config_CCR3.Channel = Channel_TIM2_UP_TIM2_CH3;
		WHT_TIMER->DMA_Config_CCR4.Stream = Stream_TIM2_CH2_TIM2_CH4; WHT_TIMER->DMA_Config_CCR4.Channel = Channel_TIM2_CH2_TIM2_CH4;
		break;
	case Timer3:
		WHT_TIMER->DMA_Config_CCR1.Stream = Stream_TIM3_CH1_TIM3_TRIG; WHT_TIMER->DMA_Config_CCR1.Channel = Channel_TIM3_CH1_TIM3_TRIG;
		WHT_TIMER->DMA_Config_CCR2.Stream = Stream_TIM3_CH2;           WHT_TIMER->DMA_Config_CCR2.Channel = Channel_TIM3_CH2;
		WHT_TIMER->DMA_Config_CCR3.Stream = Stream_TIM3_CH3;           WHT_TIMER->DMA_Config_CCR3.Channel = Channel_TIM3_CH3;
		WHT_TIMER->DMA_Config_CCR4.Stream = Stream_TIM3_CH4_TIM3_UP;   WHT_TIMER->DMA_Config_CCR4.Channel = Channel_TIM3_CH4_TIM3_UP;
		break;
	case Timer4:
		WHT_TIMER->DMA_Config_CCR1.Stream = Stream_TIM4_CH1;  WHT_TIMER->DMA_Config_CCR1.Channel = Channel_TIM4_CH1;
		WHT_TIMER->DMA_Config_CCR2.Stream = Stream_TIM4_CH2;  WHT_TIMER->DMA_Config_CCR2.Channel = Channel_TIM4_CH2;
		WHT_TIMER->DMA_Config_CCR3.Stream = Stream_TIM4_CH3;  WHT_TIMER->DMA_Config_CCR3.Channel = Channel_TIM4_CH3;
		//WHT_TIMER->DMA_Config_CCR4.Stream = 0;                WHT_TIMER->DMA_Config_CCR4.Channel = 0;
		break;
	case Timer5:
		WHT_TIMER->DMA_Config_CCR1.Stream = Stream_TIM5_CH1;             WHT_TIMER->DMA_Config_CCR1.Channel = Channel_TIM5_CH1;
		WHT_TIMER->DMA_Config_CCR2.Stream = Stream_TIM5_CH2;             WHT_TIMER->DMA_Config_CCR2.Channel = Channel_TIM5_CH2;
		WHT_TIMER->DMA_Config_CCR3.Stream = Stream_TIM5_CH3_TIM5_UP;     WHT_TIMER->DMA_Config_CCR3.Channel = Channel_TIM5_CH3_TIM5_UP;
		WHT_TIMER->DMA_Config_CCR4.Stream = Stream_TIM5_CH4_TIM5_TRIG_1; WHT_TIMER->DMA_Config_CCR4.Channel = Channel_TIM5_CH4_TIM5_TRIG_1;
		break;
	case Timer8:
		WHT_TIMER->DMA_Config_CCR1.Stream = Stream_TIM8_CH1;                    WHT_TIMER->DMA_Config_CCR1.Channel = Channel_TIM8_CH1;
		WHT_TIMER->DMA_Config_CCR2.Stream = Stream_TIM8_CH2;                    WHT_TIMER->DMA_Config_CCR2.Channel = Channel_TIM8_CH2;
		WHT_TIMER->DMA_Config_CCR3.Stream = Stream_TIM8_CH3;                    WHT_TIMER->DMA_Config_CCR3.Channel = Channel_TIM8_CH3;
		WHT_TIMER->DMA_Config_CCR4.Stream = Stream_TIM8_CH4_TIM8_TRIG_TIM8_COM; WHT_TIMER->DMA_Config_CCR4.Channel = Channel_TIM8_CH4_TIM8_TRIG_TIM8_COM;
		break;
	default:break;
	}

	/*PWM输出及互补输出*/
	for (unsigned char i = 0; i < config->Config_Count; i++)
	{
		timer_oc_parameter_struct  TIM_OCInitStruct;

		/*输出使能*/
		TIM_OCInitStruct.outputstate = TIMER_CCX_ENABLE;
		/*输出通道电平极性配置*/
		TIM_OCInitStruct.ocpolarity = PWM_Config[i].Normal_Polarity == Hig ? TIMER_OC_POLARITY_HIGH : TIMER_OC_POLARITY_LOW;
		/*输出通道空闲电平极性配置*/
		TIM_OCInitStruct.ocidlestate = PWM_Config[i].Normal_Idle_Polarity == Hig ? TIMER_OC_IDLE_STATE_HIGH : TIMER_OC_IDLE_STATE_LOW;
		
		/*******************互补输出*******************/
		TIM_OCInitStruct.outputnstate = PWM_Config[i].Complementary_Output_State == ENABLE ? TIMER_CCXN_ENABLE : TIMER_CCXN_DISABLE;
		if (PWM_Config[i].Complementary_Output_State == ENABLE)
		{
			/*互补输出通道电平极性配置*/
			TIM_OCInitStruct.ocnpolarity = PWM_Config[i].CO_Polarity == Hig ? TIMER_OCN_POLARITY_HIGH : TIMER_OCN_POLARITY_LOW;
			/*互补输出通道空闲电平极性配置*/
			TIM_OCInitStruct.ocnidlestate = PWM_Config[i].CO_Idle_Polarity == Hig ? TIMER_OCN_IDLE_STATE_HIGH : TIMER_OCN_IDLE_STATE_LOW;
		}

		if (PWM_Config[i].Channel == Timer_CH1)
		{
			timer_channel_output_mode_config(config->Name, TIMER_CH_0, TIMER_OC_MODE_PWM0); //输出模式
			timer_channel_output_pulse_value_config(config->Name, TIMER_CH_0, 0);           //输出占空比
			timer_channel_output_config(config->Name, TIMER_CH_0, &TIM_OCInitStruct);
			timer_channel_output_shadow_config(config->Name, TIMER_CH_0, TIMER_OC_SHADOW_ENABLE);//影子寄存器开启
			/*将注册到DMA上*/
			WHT_TIMER->DMA_Config_CCR1.IT_Callback = PWM_Config[i].Idle_IT_Callback;
			WHT_DMA_BSP.WHT_Register(&WHT_TIMER->DMA_Config_CCR1);
		}
		else if (PWM_Config[i].Channel == Timer_CH2)
		{
			timer_channel_output_mode_config(config->Name, TIMER_CH_1, TIMER_OC_MODE_PWM0); //输出模式
			timer_channel_output_pulse_value_config(config->Name, TIMER_CH_1, 0);           //输出占空比
			timer_channel_output_config(config->Name, TIMER_CH_1, &TIM_OCInitStruct);
			timer_channel_output_shadow_config(config->Name, TIMER_CH_1, TIMER_OC_SHADOW_ENABLE);//影子寄存器开启
			/*将注册到DMA上*/
			WHT_TIMER->DMA_Config_CCR2.IT_Callback = PWM_Config[i].Idle_IT_Callback;//定时器3没有通道2的DMA 注意
			WHT_DMA_BSP.WHT_Register(&WHT_TIMER->DMA_Config_CCR2);
		}
		else if (PWM_Config[i].Channel == Timer_CH3)
		{
			timer_channel_output_mode_config(config->Name, TIMER_CH_2, TIMER_OC_MODE_PWM0); //输出模式
			timer_channel_output_pulse_value_config(config->Name, TIMER_CH_2, 0);           //输出占空比
			timer_channel_output_config(config->Name, TIMER_CH_2, &TIM_OCInitStruct);
			timer_channel_output_shadow_config(config->Name, TIMER_CH_2, TIMER_OC_SHADOW_ENABLE);//影子寄存器开启
			/*将注册到DMA上*/
			WHT_TIMER->DMA_Config_CCR3.IT_Callback = PWM_Config[i].Idle_IT_Callback;
			WHT_DMA_BSP.WHT_Register(&WHT_TIMER->DMA_Config_CCR3);
		}
		else if (PWM_Config[i].Channel == Timer_CH4)
		{
			timer_channel_output_mode_config(config->Name, TIMER_CH_3, TIMER_OC_MODE_PWM0); //输出模式
			timer_channel_output_pulse_value_config(config->Name, TIMER_CH_3, 0);           //输出占空比
			timer_channel_output_config(config->Name, TIMER_CH_3, &TIM_OCInitStruct);
			timer_channel_output_shadow_config(config->Name, TIMER_CH_3, TIMER_OC_SHADOW_ENABLE);//影子寄存器开启
			/*将注册到DMA上*/
			WHT_TIMER->DMA_Config_CCR4.IT_Callback = PWM_Config[i].Idle_IT_Callback;
			WHT_DMA_BSP.WHT_Register(&WHT_TIMER->DMA_Config_CCR4);
		}
	}
}
/*高级定时器刹车和死区*/
static void WHT_Timer_BSP_Break(const WHT_Timer_Config_t* config)
{
	WHT_Timer_PWM_Out_Config_t* PWM_Config = (WHT_Timer_PWM_Out_Config_t*)config->Config;
	timer_break_parameter_struct TIM_BDTRInitStruct;

	for (unsigned char i = 0; i < config->Config_Count; i++)
	{
		/*有关刹车和死区结构体的成员具体可参考BDTR寄存器的描述*/
		TIM_BDTRInitStruct.breakstate = PWM_Config[i].Brake_Output_State == ENABLE ? TIMER_BREAK_ENABLE : TIMER_BREAK_DISABLE;
		if (PWM_Config[i].Brake_Output_State == ENABLE)
		{
			TIM_BDTRInitStruct.runoffstate = TIMER_ROS_STATE_ENABLE;
			TIM_BDTRInitStruct.ideloffstate = TIMER_IOS_STATE_ENABLE;
			TIM_BDTRInitStruct.protectmode = TIMER_CCHP_PROT_OFF;//TIM_LOCKLevel_1;//寄存器写保护
			/*输出比较信号死区时间配置，具体如何计算可参考 BDTR:UTG[7:0]的描述*/
			/* 死区时间配置 (典型值500ns:36,152ns:11) */
			TIM_BDTRInitStruct.deadtime = 36;
			/////////////TIM_BDTRInitStruct.breakstate = TIM_Break_Disable;////////TIM_Break_Enable;//刹车输入检测
			/*当BKIN引脚检测到高电平的时候，输出比较信号被禁止，刹车*/
			TIM_BDTRInitStruct.breakpolarity = TIMER_BREAK_POLARITY_LOW;
			TIM_BDTRInitStruct.outputautostate = TIMER_OUTAUTO_ENABLE;
		}
		timer_break_config(config->Name, &TIM_BDTRInitStruct);
		timer_channel_control_shadow_config(config->Name, DISABLE); // 禁用通道捕获/比较控制影子寄存器
	}
}
/*定时器输入捕获*/
static void WHT_Timer_BSP_Input_Capture(const WHT_Timer_Config_t* config)//目前未调试未完成
{
	// 使用PWM输入模式时，需要占用两个捕获寄存器，一个测周期，另外一个测占空比
	timer_ic_parameter_struct  TIM_ICInitStructure;
	// 捕获通道IC1配置

	// 设置捕获的边沿
	TIM_ICInitStructure.icpolarity = TIMER_IC_POLARITY_RISING;
	// 设置捕获通道的信号来自于哪个输入通道，有直连和非直连两种
	TIM_ICInitStructure.icselection = TIMER_IC_SELECTION_DIRECTTI;
	// 1分频，即捕获信号的每个有效边沿都捕获
	TIM_ICInitStructure.icprescaler = TIMER_IC_PSC_DIV1;
	// 不滤波
	TIM_ICInitStructure.icfilter = 0;
	// 初始化PWM输入模式   选择捕获通道1
	timer_input_capture_config(config->Name, TIMER_CH_0, &TIM_ICInitStructure);
			
	// 当工作做PWM输入模式时,只需要设置触发信号的那一路即可（用于测量周期）
	// 另外一路（用于测量占空比）会由硬件自带设置，不需要再配置
		
	// 捕获通道IC2配置

		
	// 选择输入捕获的触发信号
	timer_input_trigger_source_select(config->Name, TIMER_SMCFG_TRGSEL_ITI0);

	// 选择从模式: 复位模式
	// PWM输入模式时,从模式必须工作在复位模式，当捕获开始时,计数器CNT会被复位
	timer_slave_mode_select(config->Name, TIMER_SLAVE_MODE_RESTART);
	timer_master_slave_mode_config(config->Name, TIMER_MASTER_SLAVE_MODE_ENABLE);

	// 使能捕获中断,这个中断针对的是主捕获通道（测量周期那个）
	timer_interrupt_enable(config->Name, TIMER_INT_CH0);
	// 清除中断标志位
	timer_interrupt_flag_clear(config->Name, TIMER_INT_FLAG_CH0);
}
/*定时器配置*/
static void WHT_Timer_BSP_Config(const WHT_Timer_Config_t* config)
{
    if (config->Private_Data != NULL)
        return;

	switch (config->Name)
	{
	case Timer1:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER1; break;
	case Timer2:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER2; break;
	case Timer3:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER3; break;
	case Timer4:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER4; break;
	case Timer5:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER5; break;
	case Timer6:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER6; break;
	case Timer7:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER7; break;
	case Timer8:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER8; break;
	case Timer9:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER9; break;
	case Timer10:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER10; break;
	case Timer11:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER11; break;
	case Timer12:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER12; break;
	case Timer13:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER13; break;
	case Timer14:((WHT_Timer_Config_t*)config)->Private_Data = &WHT_TIMER14; break;
	default: return;
	}

	WHT_Timer_BSP_Set_Time(config);
	if (config->Mode == Timer_Basic)//基本定时
	{
		WHT_Timer_BSP_Basic(config);
	}
	else if (config->Mode == Timer_Output_Trigger)
	{
		WHT_Timer_BSP_Output_Trigger(config);
	}
	else if (config->Mode == Timer_Output_Comparison)//输出比较
	{
		WHT_Timer_BSP_GPIO_Init(config);
		WHT_Timer_BSP_Output_Comparison(config);
		WHT_Timer_BSP_Break(config);
		/*主输出使能，当使用的是通用定时器时，这句可不需要*/
		timer_primary_output_config(config->Name, ENABLE);
	}
	else if (config->Mode == Timer_Input_Capture)//输入捕获
	{
		WHT_Timer_BSP_GPIO_Init(config);
		WHT_Timer_BSP_Input_Capture(config);
	}
	timer_disable(config->Name);//关闭计数器
}


/*高级定时器设置周期*/
static void WHT_Timer_BSP_Set_Cycle(const WHT_Timer_Config_t* config)
{
	unsigned int Clk_Div;
	double Cycle;

	Cycle = config->Cycle_ns * ((double)SystemCoreClock / 1000000000.0);
    for (Clk_Div = 1; Clk_Div < 65536; Clk_Div++)
    {
        if (Cycle / Clk_Div <= 65536)
            break;
    }
	/*保存自动重装载值即分辨率*/
	((WHT_Timer_Config_t*)config)->Auto_Reload = Cycle / Clk_Div - 1;
	/*设置预分频*/
	timer_prescaler_config(config->Name, Clk_Div - 1, TIMER_PSC_RELOAD_UPDATE);
	/*设置自动重装载值*/
	timer_autoreload_value_config(config->Name, config->Auto_Reload);
}
/*高级定时器设置占空比*/
static void WHT_Timer_BSP_Set_Duty_Cycle(const WHT_Timer_Config_t* config, WHT_Timer_Channel_enum channel, float duty_cycle)
{
	unsigned short compare_value = (unsigned short)(config->Auto_Reload * duty_cycle / 100.0f);

	switch (channel)
	{
	case Timer_CH1:timer_channel_output_pulse_value_config(config->Name, TIMER_CH_0, compare_value);break;
	case Timer_CH2:timer_channel_output_pulse_value_config(config->Name, TIMER_CH_1, compare_value);break;
	case Timer_CH3:timer_channel_output_pulse_value_config(config->Name, TIMER_CH_2, compare_value);break;
	case Timer_CH4:timer_channel_output_pulse_value_config(config->Name, TIMER_CH_3, compare_value);break;
	default:
		break;
	}
}
/*高级、通用定时器 每个周期DMA修改缓存里的占空比*/
static void WHT_Timer_BSP_DMA_Set_Duty_Cycle(const WHT_Timer_Config_t* config, WHT_Timer_Channel_enum channel, unsigned short* duty_cycle_buffer, unsigned short duty_cycle_count)
{
	WHT_DMA_Config_t* DMA_Send_Config_CCRx;
    dma_single_data_parameter_struct DMA_InitStruct =
    {
        .periph_addr            = (unsigned int)0,            //外设地址
        .memory0_addr           = (unsigned int)0,            //存储器地址
        .direction              = DMA_MEMORY_TO_PERIPH,       //M->P
        .number                 = 0,                          //传输个数
        .circular_mode          = DMA_CIRCULAR_MODE_DISABLE,  //单次模式
        .periph_inc             = DMA_PERIPH_INCREASE_DISABLE,//外设地址不递增
        .memory_inc             = DMA_MEMORY_INCREASE_ENABLE, //存储器地址递增
        .periph_memory_width    = DMA_PERIPH_WIDTH_16BIT,     //外设数据大小为2字节   需要将WS2812B使用的内存由1字节更改为2字节了 要不然这里需要使用 dma_multi_data_parameter_struct 这个DMA结构体了
        .priority               = DMA_PRIORITY_LOW,           //优先级最低
    };

	switch (channel)
	{
	case Timer_CH1:
		DMA_Send_Config_CCRx = &WHT_TIMER->DMA_Config_CCR1;
		DMA_InitStruct.periph_addr = config->Name + 0x34U;break;//外设基地址
	case Timer_CH2:
		DMA_Send_Config_CCRx = &WHT_TIMER->DMA_Config_CCR2;
		DMA_InitStruct.periph_addr = config->Name + 0x38U;break;
	case Timer_CH3:
		DMA_Send_Config_CCRx = &WHT_TIMER->DMA_Config_CCR3;
		DMA_InitStruct.periph_addr = config->Name + 0x3CU;break;
	case Timer_CH4:
		DMA_Send_Config_CCRx = &WHT_TIMER->DMA_Config_CCR4;
		DMA_InitStruct.periph_addr = config->Name + 0x40U;break;
	default:
		return;
	}
    DMA_InitStruct.memory0_addr = (unsigned int)duty_cycle_buffer;//数据源首地址
    DMA_InitStruct.number = duty_cycle_count;                     //传输数据个数

	DMA_Send_Config_CCRx->DMA_InitStruct = &DMA_InitStruct;
    while (DMA_Send_Config_CCRx->Info->BSP_Mutex == SET);//等待没有外设使用此通道的DMA
    DMA_Send_Config_CCRx->Info->BSP_Mutex = SET;         //DMA通道上锁
    WHT_DMA_BSP.WHT_Config(DMA_Send_Config_CCRx);        //配置当前DMA

	/*使能DMA发送请求*/
	switch (channel)
	{
	case Timer_CH1:timer_dma_enable(config->Name, TIMER_DMA_CH0D);break;
	case Timer_CH2:timer_dma_enable(config->Name, TIMER_DMA_CH1D);break;
	case Timer_CH3:timer_dma_enable(config->Name, TIMER_DMA_CH2D);break;
	case Timer_CH4:timer_dma_enable(config->Name, TIMER_DMA_CH3D);break;
	default:
		return;
	}
	timer_enable(config->Name);
}
/*基本定时器启动*/
static void WHT_Timer_BSP_Start(const WHT_Timer_Config_t* config)
{
    timer_enable(config->Name);
}
/*基本定时器暂停*/
static void WHT_Timer_BSP_Stop(const WHT_Timer_Config_t* config)
{
    timer_disable(config->Name);
}


/*全局常量*/
const WHT_Timer_BSP_t WHT_Timer_BSP =
{
	.WHT_Config         = WHT_Timer_BSP_Config,
	.WHT_Set_Cycle_ns   = WHT_Timer_BSP_Set_Cycle,
	.WHT_Set_Duty_Cycle = WHT_Timer_BSP_Set_Duty_Cycle,
	.WHT_Set_Duty_Cycle_DMA = WHT_Timer_BSP_DMA_Set_Duty_Cycle,
	.WHT_Start          = WHT_Timer_BSP_Start,
	.WHT_Stop           = WHT_Timer_BSP_Stop,
};




/*基本定时器更新中断回调函数*/
static void WHT_Timer_Basic_IRQHandler(uint32_t TIMx, void (*IT_CB)(void))
{
    if (timer_interrupt_flag_get(TIMx, TIMER_INT_FLAG_UP) == SET)
    {
        if (IT_CB)
			IT_CB();
        timer_interrupt_flag_clear(TIMx, TIMER_INT_FLAG_UP);
    }
}
/*通用高级定时器捕获/比较中断回调函数*/
static void WHT_Timer_CCx_IRQHandler(uint32_t TIMx, void (*IT_CB)(void))
{
    if (timer_interrupt_flag_get(TIMx, TIMER_INT_FLAG_CH0) == SET)
    {
        if (IT_CB)
			IT_CB();
        timer_interrupt_flag_clear(TIMx, TIMER_INT_FLAG_CH0);
    }
    else if (timer_interrupt_flag_get(TIMx, TIMER_INT_FLAG_CH1) == SET)
    {
        if (IT_CB)
			IT_CB();
        timer_interrupt_flag_clear(TIMx, TIMER_INT_FLAG_CH1);
    }
    else if (timer_interrupt_flag_get(TIMx, TIMER_INT_FLAG_CH2) == SET)
    {
        if (IT_CB)
			IT_CB();
        timer_interrupt_flag_clear(TIMx, TIMER_INT_FLAG_CH2);
    }
    else if (timer_interrupt_flag_get(TIMx, TIMER_INT_FLAG_CH3) == SET)
    {
        if (IT_CB)
			IT_CB();
        timer_interrupt_flag_clear(TIMx, TIMER_INT_FLAG_CH3);
    }
}
/*通用高级定时器输出比较中断回调函数*/
static void WHT_Timer_COM_IRQHandler(uint32_t TIMx, void (*IT_CB)(void))
{
    if (timer_interrupt_flag_get(TIMx, TIMER_INT_FLAG_CMT) == SET)
    {
        if (IT_CB)
			IT_CB();
        timer_interrupt_flag_clear(TIMx, TIMER_INT_FLAG_CMT);
    }
}
/*通用高级定时器触发中断回调函数*/
static void WHT_Timer_Trigge_IRQHandler(uint32_t TIMx, void (*IT_CB)(void))
{
    if (timer_interrupt_flag_get(TIMx, TIMER_INT_FLAG_TRG) == SET)
    {
        if (IT_CB)
			IT_CB();
        timer_interrupt_flag_clear(TIMx, TIMER_INT_FLAG_TRG);
    }
}
/*高级定时器刹车中断回调函数*/
static void WHT_Timer_Break_IRQHandler(uint32_t TIMx, void (*IT_CB)(void))
{
    if (timer_interrupt_flag_get(TIMx, TIMER_INT_FLAG_BRK) == SET)
    {
        if (IT_CB)
			IT_CB();
        timer_interrupt_flag_clear(TIMx, TIMER_INT_FLAG_BRK);
    }
}


/*定时器1更新中断服务程序*/
void TIMER0_UP_TIMER9_IRQHandler(void)
{
	if (timer_interrupt_flag_get(Timer1, TIMER_INT_FLAG_UP) == SET)
	{
		WHT_Timer_Basic_IRQHandler(Timer1, WHT_TIMER1.Basic_IT_CB);
	}
    else if (timer_interrupt_flag_get(Timer10, TIMER_INT_FLAG_UP) == SET)
	{
		WHT_Timer_Basic_IRQHandler(Timer10, WHT_TIMER10.Basic_IT_CB);
	}
}
/*定时器2中断服务程序*/
void TIMER1_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(Timer2, WHT_TIMER2.Basic_IT_CB);
}
/*定时器3中断服务程序*/
void TIMER2_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(Timer3, WHT_TIMER3.Basic_IT_CB);
}
/*定时器4中断服务程序*/
void TIMER3_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(Timer4, WHT_TIMER4.Basic_IT_CB);
}
/*定时器5中断服务程序*/
void TIMER4_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(Timer5, WHT_TIMER5.Basic_IT_CB);
}
/*定时器6中断服务程序*/
void TIMER5_DAC_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(Timer6, WHT_TIMER6.Basic_IT_CB);
}
/*定时器7中断服务程序*/
void TIMER6_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(Timer7, WHT_TIMER7.Basic_IT_CB);
}
/*定时器8更新中断和定时器13中断服务程序*/
void TIMER7_UP_TIMER12_IRQHandler(void)
{
	if (timer_interrupt_flag_get(Timer8, TIMER_INT_FLAG_UP) == SET)
	{
		WHT_Timer_Basic_IRQHandler(Timer8, WHT_TIMER8.Basic_IT_CB);
	}
    else if (timer_interrupt_flag_get(Timer13, TIMER_INT_FLAG_UP) == SET)
	{
		WHT_Timer_Basic_IRQHandler(Timer13, WHT_TIMER13.Basic_IT_CB);
	}
}
/*定时器9更新中断服务程序*/
void TIMER0_BRK_TIMER8_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(Timer9, WHT_TIMER9.Basic_IT_CB);
}
/*定时器11更新中断服务程序*/
void TIMER0_TRG_CMT_TIMER10_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(Timer11, WHT_TIMER11.Basic_IT_CB);
}
/*定时器12更新中断服务程序*/
void TIMER7_BRK_TIMER11_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(Timer12, WHT_TIMER12.Basic_IT_CB);
}
/*定时器14更新中断服务程序*/
void TIMER7_TRG_CMT_TIMER13_IRQHandler(void)
{
    WHT_Timer_Basic_IRQHandler(Timer14, WHT_TIMER14.Basic_IT_CB);
}
